package com.ocom.payhandle.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ocom.common.constant.PayHandleUrl;
import com.ocom.common.entity.card.*;
import com.ocom.common.entity.human.EntityPersonnelInfo;
import com.ocom.common.entity.pay.EntityAbnormal;
import com.ocom.common.enums.ResultEnum;
import com.ocom.common.request.payhandle.CheckPayRequest;
import com.ocom.common.request.payhandle.GzhMngHandleRequest;
import com.ocom.common.request.payhandle.GzhRechageRefundRequest;
import com.ocom.common.request.payhandle.QrCardPayRequest;
import com.ocom.common.resp.Result;
import com.ocom.common.utils.DateUtils;
import com.ocom.common.utils.ResultUtil;
import com.ocom.common.vo.pay.CallBackVo;
import com.ocom.payhandle.feign.XfRecordFeign;
import com.ocom.payhandle.fun.PayFunService;
import com.ocom.payhandle.mq.business.saveorder.SaveOrderProductService;
import com.ocom.payhandle.service.*;
import com.ocom.payhandle.vo.MqSaveOrderVo;
import com.ocom.redis.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @Description: 公众号支付
 * @Author: 朱晖
 * @Date: 2022/6/30
 **/
@Slf4j
@RestController
public class GzhController {

	@Autowired
	private XfSubAccountListService xfSubAccountListService;

	@Autowired
	XfRecordProcessService xfRecordProcessService;

	@Autowired
	AbnormalService abnormalService;

	@Autowired
	PayFunService payFunService;

	@Autowired
	private PersonnelInfoService personnelInfoService;

	@Autowired
	private XfMerchantInfoService xfMerchantInfoService;

	@Autowired
	private XfAccountInfoService xfAccountInfoService;

	@Autowired
	private SaveOrderProductService saveOrderProductService;

	@Autowired
	private XfRecordFeign xfRecordFeign;

	@PostMapping(PayHandleUrl.URL_PreOrder)
	public Result preOrder(@RequestBody EntityXfRecordProcess entityXfRecord){
		if (entityXfRecord.getSubAccount() !=null && entityXfRecord.getSubAccount() > 0) {
			xfSubAccountListService.getUserSubAccount(
					entityXfRecord.getComId(),
					entityXfRecord.getPId(),
					entityXfRecord.getSubAccount()
			);
		}
		Integer in = xfRecordProcessService.insertEntityXfRecord(entityXfRecord.getComId(),entityXfRecord);
		if(in==null || in == 0){
			return ResultUtil.error(ResultEnum.Err_4024);
		}
		return ResultUtil.success(entityXfRecord);
	}

	@PostMapping(PayHandleUrl.URL_updateEntityXfRecord)
	public Result updateEntityXfRecord(@RequestBody EntityXfRecordProcess entityXfRecord){
		Integer in = xfRecordProcessService.updateEntityXfRecord(entityXfRecord.getComId(),entityXfRecord);
		if(in==null || in == 0){
			return ResultUtil.error(ResultEnum.Err_3014);
		}
		return ResultUtil.success(entityXfRecord);
	}

	@PostMapping(PayHandleUrl.URL_callback)
	public Result callback(@RequestBody CallBackVo callBackVo){
		try {
			Result result=xfRecordProcessService.callback(callBackVo.getCompanyId(),callBackVo);
			if(result.getCode()!=200){
				return result;
			}
			if (callBackVo.getPlatOrderNo().startsWith("CART") && callBackVo.getStatus() == 1) {
				try {
					List<EntityXfRecordProcess> processList = xfRecordProcessService.cartOrders(callBackVo.getCompanyId(), callBackVo.getPlatOrderNo());
					//新增成功表的退款数据
					for (EntityXfRecordProcess entityXfRecordProcess : processList) {
						MqSaveOrderVo mqSaveOrderVo = new MqSaveOrderVo();
						mqSaveOrderVo.setComId(callBackVo.getCompanyId());
						mqSaveOrderVo.setId(entityXfRecordProcess.getId());
						mqSaveOrderVo.setMachNo(entityXfRecordProcess.getDeviceNo());
						saveOrderProductService.saveOrder(JSON.toJSONString(mqSaveOrderVo));
					}
				} catch (Exception e) {
					StackTraceElement ste = e.getStackTrace()[0];
					log.info("请求方式0aFhcBNX:【{}】,迁移购物车参数:【{}】,异常的返回:【{}】,行号:【{}】", "支付请求（退款）", callBackVo, e, ste.getLineNumber());
				}
			}

		}catch (Exception e){
			//记录异常
			EntityAbnormal entityAbnormal=new EntityAbnormal();
			entityAbnormal.setComId(callBackVo.getCompanyId());
			entityAbnormal.setPlatOrderNo(callBackVo.getPlatOrderNo());
			//1.回调异常记录
			entityAbnormal.setType(1);
			Integer length= e.getMessage().length()>200?200:e.getMessage().length();
			entityAbnormal.setRemark(e.getMessage().substring(0,length));
			abnormalService.Add(callBackVo.getCompanyId(),entityAbnormal);
			log.info("支付回调异常，  【{}】",e);
			return ResultUtil.info(4027,e.getMessage().substring(0,length));
		}
		return ResultUtil.success();
	}



	@PostMapping(PayHandleUrl.URL_getOrderInfo)
	public Result getOrderInfo(Long companyId, String tradeNo,@RequestParam(required = false,defaultValue = "") String machNo){
		EntityXfRecordProcess entityXfRecordProcess = xfRecordProcessService.selectTradeNo(companyId,tradeNo,machNo);
		if(entityXfRecordProcess ==null){
			return ResultUtil.error(ResultEnum.Err_805);
		}
		return ResultUtil.success(entityXfRecordProcess);
	}

	@Autowired
	XfZoneDateService xfZoneDateService;

	@Resource
	RedisUtil redisUtil;

	@Autowired
	private XfSignNoService xfSignNoService;


	@GetMapping("/789")
	public Result getOrderInfo(){
		return ResultUtil.success(xfZoneDateService.getTimeZone(47l,new Date()));
	}

	@GetMapping("/1234")
	public Result getOrderInfo2(){


		List<Integer> courseIds=new ArrayList<>();
		courseIds.add(1);
		courseIds.add(2);
		courseIds.add(3);

		List<EntityXfSignNo> entityXfSignNoList = xfSignNoService.getSignList(1l,28,courseIds);


		return ResultUtil.success(entityXfSignNoList);
	}


	@GetMapping("/998")
	public Result tr() {
		EntityXfRecordProcess entityXfRecordProcess = new EntityXfRecordProcess();
		entityXfRecordProcess.setMealNo("2");
		entityXfRecordProcess.setComId(651l);
		entityXfRecordProcess.setDeviceNo("23100029");
		entityXfRecordProcess.setOrderNo("DK23100029202405211617046752");
		entityXfRecordProcess.setOrigOrderNo("23100029202405211617046752");
		entityXfRecordProcess.setPayTime(new Date());
//		entityXfRecordProcess.setOrderNo("DK23100102202401171544421268");
//		entityXfRecordProcess.setOrigOrderNo("");

		payFunService.waitPayRefund(entityXfRecordProcess);
		return null;
	}



	@PostMapping(PayHandleUrl.URL_checkWithhold)
	public Result checkWithhold(@RequestBody CheckPayRequest request){
		log.info("请求方式-测试代扣:【{}】,,请求参数:【{}】", "代扣补缴", request);
		try {

			String tradeNoRedis = "testPay:" + request.getCompanyId()  + ":" + request.getOrderNo();

			if (!redisUtil.lock(tradeNoRedis, 3 * 60)) {
				log.info("请求方式:【{}】,机器号:【{}】,请求参数:【{}】,返回:【{}】", "测试补缴", request.getDeviceNo(), request, ResultUtil.error(ResultEnum.Err_802));
				//订单号重复
				return ResultUtil.error(ResultEnum.Err_802);
			}

			Long pId =  request.getPId() ;

			//判断是什么支付类型
			//9 支付宝人脸
			EntityXfRecordProcess entityXfRecordProcess = new EntityXfRecordProcess();
			entityXfRecordProcess.setDeviceNo("00000000");
			entityXfRecordProcess.setDeviceName("测试补缴:"+request.getDeviceNo());
			entityXfRecordProcess.setPId(pId);
			entityXfRecordProcess.setMerchId(request.getMerchId());
			entityXfRecordProcess.setComId(request.getCompanyId());
			EntityPersonnelInfo entityPersonnelInfo = personnelInfoService.selectPersonnel(request.getCompanyId(), pId);
			EntityXfAccountInfo entityXfAccountInfo = xfAccountInfoService.selectAccountPid(request.getCompanyId(), pId);

			if (entityXfAccountInfo == null) {
				return ResultUtil.error(ResultEnum.Err_1001);
			}
			entityXfRecordProcess.setAccountNo(entityXfAccountInfo.getAccountNo());
			entityXfRecordProcess.setAccTypeId(entityXfAccountInfo.getAccTypeId());
			entityXfRecordProcess.setPCode(entityPersonnelInfo.getPCode());
			entityXfRecordProcess.setPName(entityPersonnelInfo.getPName());

			if (entityPersonnelInfo == null || 0 != entityPersonnelInfo.getStatus()) {
				return ResultUtil.error(ResultEnum.Err_4022);
			}

			//9 微信人脸代扣 22人脸
			entityXfRecordProcess.setOpType(1l);
			entityXfRecordProcess.setOpTypeDiff(306l);
			entityXfRecordProcess.setCreateTime(new Date());
			entityXfRecordProcess.setMonthValue(DateUtils.getStrDate(new Date(), "yyyyMM"));

			//消费状态，1：消费；2：退款；3：点餐；4.取餐；5.订餐；6：退订；10：充值；11：提现；12：补贴；13：清卡；21：销户
			entityXfRecordProcess.setConsState(1);
			entityXfRecordProcess.setOrderNo(request.getOrderNo());
			entityXfRecordProcess.setConsMoney(-1l);

			//支付状态；0支付中、1支付成功，2支付失败，3撤单中，4已撤单，5退款中，6已退款，7部分退款成功
			entityXfRecordProcess.setPayState(0);
			entityXfRecordProcess.setDiscount(0l);
			entityXfRecordProcess.setRealMoney(-1l);
			entityXfRecordProcess.setPayAmount(1l);
			entityXfRecordProcess.setConsType(2);
			entityXfRecordProcess.setConsTime(new Date());
			entityXfRecordProcess.setMealNo(null);
			entityXfRecordProcess.setMealDate(null);

			if(request.getMerchId()==0l){
				entityXfRecordProcess.setPointId(0l);
				entityXfRecordProcess.setMerchName("本单位");
				entityXfRecordProcess.setPointName("本单位");
			}else{
				entityXfRecordProcess.setPointId(1l);
				EntityXfMerchantInfo entityXfMerchantInfo = xfMerchantInfoService.getMerchInfo(request.getCompanyId(),request.getMerchId().intValue());
				if(entityXfMerchantInfo!=null){
					entityXfRecordProcess.setMerchName(entityXfMerchantInfo.getMerchName());
				}
				entityXfRecordProcess.setPointName("测试");
			}

			int payState = 0;

			//第三方的支付失败结果
			JSONObject jsonObject = new JSONObject();
			//0不允许代扣  1代扣优先  2最后代扣

			//1代扣优先
			QrCardPayRequest qrCardPayRequest = new QrCardPayRequest();
			qrCardPayRequest.setCompanyId(request.getCompanyId());
			qrCardPayRequest.setTradeNo(request.getOrderNo());
			qrCardPayRequest.setAuthCode(entityXfRecordProcess.getPId().toString());
			qrCardPayRequest.setType(1);
			qrCardPayRequest.setMachNo("00000000");
			qrCardPayRequest.setConsType(entityXfRecordProcess.getConsType());
			qrCardPayRequest.setAmount(1);
			payState = payFunService.withholding(entityXfRecordProcess, qrCardPayRequest, null, jsonObject);

			log.info("【公众号补缴结果】【{}】，【{}】", payState, qrCardPayRequest);

			if (payState == 1) {
				//支付成功
				return ResultUtil.success();
			} else if (payState == -1) {
				//商户支付渠道未配置"
				return ResultUtil.error(ResultEnum.Err_3048);
			} else if (payState == -2) {
				//代扣未签约"
				return ResultUtil.error(ResultEnum.Err_3047);
			} else if (payState == -11) {
				//订单号重复
				return ResultUtil.error(ResultEnum.Err_802);
			} else if (payState == -12) {
				//余额不足
				return ResultUtil.error(ResultEnum.Err_4024);
			} else {
				//支付结果未知
				return ResultUtil.error(ResultEnum.Err_3029,jsonObject);
			}
		} catch (Exception e) {
			StackTraceElement ste = e.getStackTrace()[0];
			log.info("请求方式gzh:【{}】,机器号:【{}】,请求参数:【{}】,异常2:【{}】,行号:【{}】", "公众号测试代扣", request, request, e, ste.getLineNumber());
			return ResultUtil.error(ResultEnum.Err_3031);
		}
	}


	@PostMapping(PayHandleUrl.URL_gzhRechageRefund)
	public Result gzhRechageRefund(@RequestBody @Valid GzhRechageRefundRequest request) {
		log.info("请求方式-公众号退款:【{}】,,请求参数:【{}】", "管理员退款", request);

		String tradeNoRedis = "gzhRefund:" + request.getComId() + ":" + request.getOrigTradeNo();

		if (!redisUtil.lock(tradeNoRedis, 20)) {
			log.info("请求方式:【{}】,机器号:【{}】,请求参数:【{}】,返回:【{}】", "公众号退款", request.getComId(), request, ResultUtil.error(ResultEnum.Err_4102));
			//订单号重复
			return ResultUtil.error(ResultEnum.Err_4102);
		}

		return payFunService.gzhRefund(request);

	}


	@PostMapping(PayHandleUrl.URL_gzhRechageRefundMng)
	public Result gzhRechageRefundMng(@RequestBody @Valid GzhMngHandleRequest request) {
		log.info("请求方式-公众号退款成功 修改状态 推送成功库:【{}】,,请求参数:【{}】", "管理员退款", request);

		String tradeNoRedis = "gzhRechageRefund:" + request.getComId()  + ":" + request.getId();

		if (!redisUtil.lock(tradeNoRedis, 30)) {
			return ResultUtil.error(ResultEnum.Err_4102);
		}

		EntityXfRecordProcess entityXfRecordProcess = xfRecordProcessService.selectTradeNo(request.getComId(), request.getId());
		if (entityXfRecordProcess == null) {
			//原订单号不存在
			return ResultUtil.error(ResultEnum.Err_3036);
		}
		if (entityXfRecordProcess.getConsState() != 11 || entityXfRecordProcess.getPayState() != 5) {
			//原订单号不存在
			return ResultUtil.error(ResultEnum.Err_3207);
		}

		if (entityXfRecordProcess.getSubAccount() > 0 || entityXfRecordProcess.getOpTypeDiff() < 200) {
			//暂不支持
			return ResultUtil.error(ResultEnum.Err_3205);
		}


		EntityXfRecordProcess entityXfRecordProcessOrg = xfRecordProcessService.selectTradeNo(request.getComId(), entityXfRecordProcess.getOrigOrderNo(), entityXfRecordProcess.getDeviceNo());
		if (entityXfRecordProcessOrg == null) {
			//原订单号不存在
			return ResultUtil.error(ResultEnum.Err_3036);
		}

		EntityXfAccountInfo entityXfAccountInfo = xfAccountInfoService.selectAccountPid(request.getComId(), entityXfRecordProcess.getPId());
		if (entityXfAccountInfo == null || entityXfAccountInfo.getAccountState() != 0) {
			//账号异常
			return ResultUtil.error(ResultEnum.Err_3105);
		}

		if(request.getStatus()){
			//修改等待表的原订单表的数据
			Date payTime = new Date();
			EntityXfRecordProcess updateXfRecordProcess = new EntityXfRecordProcess();
			updateXfRecordProcess.setId(entityXfRecordProcessOrg.getId());
			updateXfRecordProcess.setRefundTime(payTime);
			updateXfRecordProcess.setIfRefund(1l);
			updateXfRecordProcess.setPayState(1);

			try {

				EntityXfRecordProcess updateXfRecordRefund =  new EntityXfRecordProcess();
				updateXfRecordRefund.setId(entityXfRecordProcess.getId());
				updateXfRecordRefund.setPayTime(payTime);
				updateXfRecordRefund.setPayState(1);
				updateXfRecordRefund.setChargeMoney(entityXfRecordProcess.getChargeMoney());
				updateXfRecordRefund.setSubMoney(entityXfRecordProcess.getSubMoney());
				updateXfRecordRefund.setPayAmount(-1 * entityXfRecordProcess.getPayAmount());
				if (entityXfRecordProcess.getSubMoney() != 0 && -1 * entityXfRecordProcess.getSubMoney() > entityXfAccountInfo.getAccountSubsidyMoney()) {
					updateXfRecordRefund.setSubMoney(-1 * entityXfAccountInfo.getAccountSubsidyMoney());
				}
				updateXfRecordRefund.setChargeBalance(entityXfAccountInfo.getAccountRechargeMoney() + updateXfRecordRefund.getChargeMoney());
				updateXfRecordRefund.setSubBalance(entityXfAccountInfo.getAccountSubsidyMoney() + updateXfRecordRefund.getSubMoney());

				xfAccountInfoService.gzhRefundOrderStatusSucc(request.getComId(), updateXfRecordProcess,updateXfRecordRefund);
			} catch (Exception e) {
				StackTraceElement ste = e.getStackTrace()[0];
				log.info("请求方式236gzhRechageRefundSucc:【{}】,机器号:【{}】,入库修改的数据:【{}】,异常的返回:【{}】,行号:【{}】", "公众号退款", request.getId(), updateXfRecordProcess, e, ste.getLineNumber());
				return ResultUtil.error(ResultEnum.Err_3039);
			}

			//修改成功表的原订单表的数据
			updateXfRecordProcess.setComId(request.getComId());
			updateXfRecordProcess.setOrderNo(entityXfRecordProcessOrg.getOrderNo());
			updateXfRecordProcess.setMonthValue(entityXfRecordProcessOrg.getMonthValue());
			updateXfRecordProcess.setDeviceNo(entityXfRecordProcessOrg.getDeviceNo());
			EntityXfRecord entityXfRecord = JSON.parseObject(JSON.toJSONString(updateXfRecordProcess), EntityXfRecord.class);
			Result result = xfRecordFeign.updateXfRecord(entityXfRecord);
			if (result.getCode() != 200) {
				log.info("请求方式37GZh:【{}】,机器号:【{}】,修改成功表的数据:【{}】,返回:【{}】", "管理员退款", request.getId(), entityXfRecordProcess, "修改原订单信息失败");
			}

			//新增成功表的退款数据
			try {
				MqSaveOrderVo mqSaveOrderVo = new MqSaveOrderVo();
				mqSaveOrderVo.setComId(request.getComId());
				mqSaveOrderVo.setId(entityXfRecordProcess.getId());
				mqSaveOrderVo.setMachNo(entityXfRecordProcess.getDeviceNo());
				saveOrderProductService.saveOrder(JSON.toJSONString(mqSaveOrderVo));
			} catch (Exception e) {
				StackTraceElement ste = e.getStackTrace()[0];
				log.info("请求方式1006:【{}】,机器号:【{}】,扫码退款-插成功库:【{}】,异常的返回:【{}】,行号:【{}】", "支付请求（退款）", entityXfRecordProcess.getDeviceNo(), entityXfRecordProcess, e, ste.getLineNumber());
			}
			return ResultUtil.success();

		}else{
			//明确失败的 补回金额
			try {
				entityXfRecordProcess.setPayState(2);

				//原订单
				EntityXfRecordProcess updateXfRecordProcess = new EntityXfRecordProcess();
				updateXfRecordProcess.setId(entityXfRecordProcessOrg.getId());
				updateXfRecordProcess.setPayState(1);

				xfAccountInfoService.gzhRefundOrderStatusFail(request.getComId(), entityXfAccountInfo.getId(), entityXfRecordProcess, updateXfRecordProcess);
			} catch (Exception e) {
				StackTraceElement ste = e.getStackTrace()[0];
				log.info("请求方式236gzhRechageRefundFail:【{}】,机器号:【{}】,入库修改的数据:【{}】,异常的返回:【{}】,行号:【{}】", "公众号退款补回", request.getId(), entityXfRecordProcess, e, ste.getLineNumber());
				return ResultUtil.error(ResultEnum.Err_3035);
			}

			return ResultUtil.success();
		}

	}



}
